using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using SqlScriptCreator.Generators;
using System.Configuration;
using System.IO;
using ICSharpCode.TextEditor.Document;
using System.Threading;

namespace SqlScriptCreator
{
    public partial class Frontend : Form
    {
    	private DataTable dtParameters;
        private DataSet dsQueryResult;

        public Frontend()
        {
            Thread th = new Thread(new ThreadStart(DoSplash));
            th.Start();
            InitializeComponent();
            Thread.Sleep(1000);
            th.Abort();
        }

        private void DoSplash()
        {
            SplashScreen splash = new SplashScreen();
            splash.ShowDialog();
        }

        private void btExecute_Click(object sender, EventArgs e)
        {
            SqlConnectionStringBuilder csb = new SqlConnectionStringBuilder();
            csb.IntegratedSecurity = cbIntegratedAuth.Checked;
            csb.UserID = tbUser.Text;
            csb.Password = tbPassword.Text;
            csb.DataSource = cbServer.Text;
            csb.InitialCatalog = cbDatabase.Text;

            SqlConnection conn = new SqlConnection(csb.ConnectionString);

            SqlCommand cmd = new SqlCommand(teSqlQuery.Text, conn);

            try
            {
                conn.Open();
                SqlDataReader rdr = cmd.ExecuteReader();
                dtParameters = rdr.GetSchemaTable();
                rdr.Close();
                conn.Close();
                dgvParameters.DataSource = dtParameters;


                SqlDataAdapter da = new SqlDataAdapter(cmd);
                dsQueryResult = new DataSet();
                if (cbLimit.Checked)
                {
                    da.Fill(dsQueryResult, 0, 100, "Table");
                }
                else
                {
                    da.Fill(dsQueryResult, "Table");
                }

                if (dsQueryResult.Tables.Count > 0)
                    dgvQueryResult.DataSource = dsQueryResult.Tables[0];

                generateScripts();

                // activate result tab
                tabControl1.SelectedIndex = 1;
            }
            catch (SqlException sqle)
            {
                MessageBox.Show(sqle.Message, "SQL Error");
            }
            catch (InvalidOperationException)
            {
                MessageBox.Show(Properties.Resources.ErrorEnterSqlQuery, Properties.Resources.Error);
            }
        }

        private void generateScripts() {
            string script = "";
        	if (pgGeneratorSettings.SelectedObject != null) {
				IScriptGenerator generator = (IScriptGenerator) pgGeneratorSettings.SelectedObject;
				if (dtParameters != null && dtParameters.Rows.Count > 0) {
					DocumentFactory dc = new DocumentFactory();
                    DataTable dtResult = null;
                    if (dsQueryResult != null  && dsQueryResult.Tables.Count > 0) 
                        dtResult = dsQueryResult.Tables[0];
                    script = generator.generateScript(teSqlQuery.Text, dtResult, dtParameters);
				}
				else MessageBox.Show(Properties.Resources.ErrorNoColumnsReturned, Properties.Resources.Error);
        	}
            teScriptEditor.Document.TextContent = script;
            teScriptEditor.Refresh();
        }
        
        private void button1_Click_1(object sender, EventArgs e)
        {
            Close();
        }

	    private void cbIntegratedAuth_CheckedChanged(object sender, EventArgs e)
        {
            tbUser.Enabled = !cbIntegratedAuth.Checked;
            tbPassword.Enabled = !cbIntegratedAuth.Checked;
        }
        
        void Form1Load(object sender, System.EventArgs e)
        {
            // set default connection properties
            Properties.Settings config = Properties.Settings.Default;
            cbServer.Text = config.Server;
            cbDatabase.Text = config.Database;
            tbUser.Text = config.User;
            tbPassword.Text = config.Password;
            cbIntegratedAuth.Checked = config.IntegratedAuth;
            
        	// generate tree with script-generators
        	TreeNode rootnode = new TreeNode(Properties.Resources.ScriptGeneration, 2, 2);
            tvGenerators.Nodes.Add(rootnode);

            TreeNode tsbsnode = new TreeNode(Properties.Resources.TableStructureBasedScripts, 2, 2);
            rootnode.Nodes.Add(tsbsnode);
            foreach (IScriptGenerator generator in ScriptGeneratorManager.Instance.TableStructureBasedScripts)
            {
        		TreeNode node = new TreeNode(generator.ToString(), 1, 1);
        		node.Tag = generator;
                tsbsnode.Nodes.Add(node);
        	}

            TreeNode tdbsnode = new TreeNode(Properties.Resources.TableDataBasedScripts, 2, 2);
            rootnode.Nodes.Add(tdbsnode);
            foreach (IScriptGenerator generator in ScriptGeneratorManager.Instance.TableDataBasedScripts)
            {
                TreeNode node = new TreeNode(generator.ToString(), 1, 1);
                node.Tag = generator;
                tdbsnode.Nodes.Add(node);
            }
            
            rootnode.ExpandAll();

			// enable syntax highlighting for SQL code        	
        	ICSharpCode.TextEditor.Document.FileSyntaxModeProvider fsmProvider; 
        	fsmProvider = new FileSyntaxModeProvider(Directory.GetCurrentDirectory());
			HighlightingManager.Manager.AddSyntaxModeFileProvider(fsmProvider);
			teScriptEditor.SetHighlighting("SQL");
            teSqlQuery.SetHighlighting("SQL");
            
        }
        
        void PgGeneratorSettingsPropertyValueChanged(object s, System.Windows.Forms.PropertyValueChangedEventArgs e)
        {
        	generateScripts();
        }
        
        void TvGeneratorsAfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
        {
        	pgGeneratorSettings.SelectedObject = tvGenerators.SelectedNode.Tag; 
        	generateScripts();        	
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.F5)
            {
                this.btExecute_Click(sender, e);
                e.Handled = true;
            }
        }
    }
}
